#include "stdafx.h"

    namespace network
    {

        SBServer* SBServer::m_instance = NULL;

        SBServer::SBServer() :
        Server(),
		helper::MulticastSenderHelper( boost::asio::ip::address::from_string("225.0.0.1") ),
		m_sessionManager(),
        m_sessionCount(0),
		m_newSession(new SBServerSession(Server::m_ioService, m_sessionManager, m_sessionCount)),
		m_db(),
		m_tcpThread(boost::bind( &SBServer::run, this ))
        {
			
			//m_db.connect("weasel","weasel","weasel_db","localhost",3306);

			CONNECT( Event::EVENT_CHANGE_POSITION, &SBServer::multicastFromEvent);
			CONNECT( Event::EVENT_GROW, &SBServer::multicastFromEvent);

			CONNECT(Event::EVENT_NEED_GENERIK_ADD, &SBServer::multicastFromEvent);
			CONNECT(Event::EVENT_NEED_GENERIK_REMOVE, &SBServer::multicastFromEvent);

			CONNECT(Event::EVENT_NEED_GENERIK_SCENT_ADD, &SBServer::multicastFromEvent);
			
			CONNECT(Event::EVENT_NEED_GENERIK_REMOVE, &SBServer::multicastFromEvent);

        

        }

        SBServer::~SBServer()
        {
			//m_db.disconnect();
			
#if defined(_DEBUG) && defined(_OUTPUT)
            std::cout << " Closing speedbrick bourick Server..." << std::endl;
#endif
        }

		SBServer& SBServer::getSingleton()
        {
            if (m_instance == NULL)
                m_instance = new SBServer();

            return *m_instance;
        }

        SBServer* SBServer::getSingletonPtr()
        {
            if (m_instance == NULL)
                m_instance = new SBServer();

            return m_instance;
        }

        void SBServer::kill()
        {
			if( m_instance != NULL )
				delete m_instance;
			m_instance = NULL;
		}

		db::SBDatabaseMysql& SBServer::db()
		{
			return m_db;
		}

        void SBServer::run()
        {
            m_acceptor.async_accept(m_newSession->socket(),
                                    boost::bind(& SBServer::handle_accept,
                                                this,
                                                boost::asio::placeholders::error));

            Server::run();

        }

		void SBServer::multicastFromEvent( boost::shared_ptr< Event::EventBase > _evt )
		{
			buffer::BasicBuffer* packet = dynamic_cast< buffer::BasicBuffer* >( _evt.get() );

			if( PacketManager::getSingleton().checkPacketId( packet ) )
			{
				multicast<SBServer>( *packet, &SBServer::handle_send_to, m_instance );
			}
#if defined( _DEBUG ) && defined( _OUTPUT )
			else
				std::cout << " [ SBServer::multicastFromEvent ] Unknown packet! " << std::endl;
#endif
		}

		void SBServer::handle_send_to(const boost::system::error_code& error, size_t bytes_recvd)
		{
			if (!error)
			{
				
#if defined(_DEBUG) && defined(_OUTPUT)
				std::cout << "Server multicast from: " << m_serverEndpoint << std::endl;
#endif

			}
			else if (error == boost::asio::error::operation_aborted)
            {
				stop();
            }
			

		}

        void SBServer::handle_accept(const boost::system::error_code& e)
        {
            std::cout << " accepting connection .. " << std::endl;

            if (!e)
            {
                m_sessionManager.start(m_newSession);
                ++m_sessionCount;
                // We create a new connexion object for the new input connexion
				m_newSession.reset(new SBServerSession(Server::m_ioService, m_sessionManager, m_sessionCount));

                // Kind of loop because of the callback toward this same function
                m_acceptor.async_accept(m_newSession->socket(),
                                        boost::bind(&Server::handle_accept, this,
                                                    boost::asio::placeholders::error));
            }

        }

    } //  // namespace network
